#include<iostream>
#include<fcntl.h>
#include<string>
#include <sys/types.h>
#include <sys/stat.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ipc.h>
#include <sys/shm.h>
const char* fifo_read_pathname = "fifo-messages-client";
const char* fifo_write_pathname = "fifo-messages-server";

#define ERR_EXIT(m)\
    do{\
        perror(m);\
        exit(EXIT_FAILURE);\
    }while(0)



int flag = 1;//stop pthread
void* pthreadRead(void* argv){
    int fd = *(int*)argv;
    while (flag)
    {   
        // sleep(5);
        const int buffer_size = 1024;
        char buffer[buffer_size] = {0};
        int n = read(fd,buffer,sizeof(buffer));
        if(n == -1){
            perror("read fail");
            return NULL;
        }
        else if(n == 0){
            printf("none online\n");
            sleep(2);

        }
        buffer[n] = 0; 
        printf("\033[1;34mCLIENT:%s\033[0m\n",buffer);
    }
    pthread_exit(NULL);
}

int create_fifo(){
    if(mkfifo(fifo_write_pathname,0666) == -1){
        if(errno == EEXIST){
            printf("fifo exist\n");
        }
        else{
            perror("mkfifo fail");
            return 1;
        }
    }

    if(mkfifo(fifo_read_pathname,0666) == -1){
        if(errno == EEXIST){
            printf("fifo exist\n");
        }
        else{
            perror("mkfifo fail");
            return 1;
        }
    }
    return 0;
}



int main(){
    system("clear");
    create_fifo();
    int write_fd = 0,i = 1;
    while(write_fd == 0){
        write_fd = open(fifo_write_pathname,O_WRONLY);
        if(write_fd == -1){
            perror("open fail");
            return 1;
        }
        printf("try linking(%d times)\n",i++);
        sleep(1);
    }
    
    int read_fd = open(fifo_read_pathname,O_RDONLY);
    if(read_fd == -1){
        perror("open fail");
        return 1;
    }
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,pthreadRead,&read_fd) != 0){
        perror("pthread_create fail");
        return 1;
    }
    pthread_detach(thread_id);//create pthread to read messages
    printf("----SERVER SIDE----\n");
    std::string input;
    while(std::getline(std::cin,input)){
        if(strcmp(input.c_str(),"quit") == 0 || write(write_fd,input.c_str(),input.size()) == -1){
            printf("----someone ends chat----\n");
            break;
        }
        std::cout << "\033[1;32mSERVER:" + input << "\033[0m" << std::endl;
    }
    flag = 0;
    close(write_fd);
    close(read_fd);
}